﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebMVC.Models;
using BackEnd.Facade.Interfaces;
using BackEnd.Facade.Implementations;
using Domain;
using WebMVC.Helpers;
using System.Web.Security;
using System.Web.Profile;

namespace WebMVC.Controllers
{
    public class TaxiController : ControllerBase
    {
        private static readonly int LAST_REVIEWS_COUNT = 6;
        private static readonly int TOP_TAXIS_COUNT = 10;
        private static readonly int TOP_TAXISBYDIST_COUNT = 5;

        protected ITaxiServiceManager _taxiManager;
        protected IFeedbackManager _feedbackManager;
        public TaxiController(ITaxiServiceManager taxiManager, IFeedbackManager feedbackManager)
        {
            this._taxiManager = taxiManager;
            this._feedbackManager = feedbackManager;
        }
        public TaxiController()
            : this(new TaxiServiceManager(), new FeedbackManager())
        {
        }
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult GetTaxisBy(TaxiSortBy sortBy)
        {
            var topTen = _taxiManager.GetTopTaxis(sortBy, TOP_TAXIS_COUNT);
            var model = ConvertToViewModel(topTen);
            return PartialView(model);
        }

        public ActionResult RecommendTaxi(short? districtId)
        {
            List<TaxiService> popular = null;
            List<TaxiService> cheapest = null;
            List<TaxiService> highestRate = null;
            List<TaxiService> comfortable = null;
            if (districtId.HasValue)
            {
                popular = _taxiManager.GetTopTaxisByDistrict(TaxiSortBy.Popular, TOP_TAXISBYDIST_COUNT, districtId.Value);
                cheapest = _taxiManager.GetTopTaxisByDistrict(TaxiSortBy.Cheapest, TOP_TAXISBYDIST_COUNT, districtId.Value);
                highestRate = _taxiManager.GetTopTaxisByDistrict(TaxiSortBy.HighestRating, TOP_TAXISBYDIST_COUNT, districtId.Value);
                comfortable = _taxiManager.GetTopTaxisByDistrict(TaxiSortBy.Comfortable, TOP_TAXISBYDIST_COUNT, districtId.Value);
            }else
            {
                popular = _taxiManager.GetTopTaxis(TaxiSortBy.Popular, TOP_TAXISBYDIST_COUNT);
                cheapest = _taxiManager.GetTopTaxis(TaxiSortBy.Cheapest, TOP_TAXISBYDIST_COUNT);
                highestRate = _taxiManager.GetTopTaxis(TaxiSortBy.HighestRating, TOP_TAXISBYDIST_COUNT);
                comfortable = _taxiManager.GetTopTaxis(TaxiSortBy.Comfortable, TOP_TAXISBYDIST_COUNT);
            }

            var model = new RecommendTaxiViewModel() 
            {
                CheapestList = ConvertToViewModel(cheapest),
                ComfortibleList = ConvertToViewModel(comfortable),
                HighestRatingList = ConvertToViewModel(highestRate),
                PopularList = ConvertToViewModel(popular),
                Districts = GetAllDistricts()
            };
            
            return View(model);
        }

        [HttpGet]
        public ActionResult Details(int id)
        {
            TaxiService service = _taxiManager.GetTaxiServiceById(id);

            var model = new TaxiDetailsViewModel()
            {
                AvgCarRating = new TaxiRating() { Rating = service.AvgCarRating },
                AvgDriverRating = new TaxiRating() { Rating = service.AvgDriverRating },
                AvgPriceRating = new TaxiRating() { Rating = service.AvgPriceRating },
                AvgRating = new TaxiRating() { Rating = service.AvgRating },
                AvgServiceRating = new TaxiRating() { Rating = service.AvgServiceRating },
                Conditioning = service.Conditioning,
                CreateDate = service.CreateDate,
                Description = GetLocalizedDescription(service),
                DistrictName = service.District != null ? GetLocalizedName(service.District) : null,
                HasMeter = service.HasMeter,
                Id = service.Id,
                LogoPath = FileStoreHelper.GetTaxiSmallLogo(service.Id, Server),
                MinPrice = service.PricePolicy.MinPrice,
                Name = GetLocalizedName(service),
                NoSmoking = service.NoSmoking,
                ParkQuantity = service.ParkQuantity,
                SpeaksEnglish = service.SpeaksEnglish,
                ServingFromYear = service.ServingFromYear,

                PhoneNumber = service.Contacts.PhoneNumber,
                PhoneNumber1 = service.Contacts.PhoneNumber1,
                PhoneNumber2 = service.Contacts.PhoneNumber2,
                PhoneNumber3 = service.Contacts.PhoneNumber3,
                PhoneNumber4 = service.Contacts.PhoneNumber4,
                PricePerKM = service.PricePolicy.PricePerKM,
                FreeWaitMinutes = service.PricePolicy.FreeWaitMinutes,
                UpTo6KMPrice = service.PricePolicy.UpTo6KMPrice,
                WaitMinutePrice = service.PricePolicy.WaitMinutePrice,
                MinPriceKM = service.PricePolicy.MinPriceKM,
                AddReviewModel = new AddReviewViewModel()
                {
                    ServiceId = id,
                    CommenterName = HttpContext.Profile.GetPropertyValue("FullName").ToString() ?? "",
                    DriverRate = new TaxiRating() { Rating = 3 },
                    PriceRate = new TaxiRating() { Rating = 3 },
                    ServiceRate = new TaxiRating() { Rating = 3 },
                    CarRate = new TaxiRating() { Rating = 3 },
                }
            };

            model.Transports = new List<TransportViewModel>();

            foreach (var transport in service.Transports)
            {
                model.Transports.Add(new TransportViewModel() { 
                    ImgPath = FileStoreHelper.GetCarSmallLogo(transport.Car.Make),
                    Name = transport.Car.Make + " " + transport.Car.Model,
                    Type = transport.Car.Type.Code
                });
            }
            return View(model);
        }

        public ActionResult LastReviews()
        {
            var feedbacks = _feedbackManager.GetLastReviews(LAST_REVIEWS_COUNT);

            var model = new List<LastReviewItemViewModel>();

            foreach (var feedback in feedbacks)
            {
                model.Add(new LastReviewItemViewModel()
                {
                    CommentDate = feedback.CreateDate,
                    UserName = feedback.UserId.HasValue ? GetUsernameById(feedback.UserId.Value) : null,
                    FullName = feedback.FullName,
                    CommentText = feedback.Comment,
                    AvgRate = new TaxiRating() { Rating = (feedback.CarRating + feedback.ServiceRating + feedback.DriverRating + feedback.PriceRating) / 4 },
                    TaxiServiceId = feedback.Service.Id,
                    TaxiServiceName = feedback.Service.NameEN,
                    LogoPath = FileStoreHelper.GetTaxiSmallLogo(feedback.Service.Id, Server)
                });
            }
            return PartialView(model);
        }

        public ActionResult Reviews(int id)
        {
            var feedbacks = _feedbackManager.GetServiceReviews(id);

            var model = new List<ReviewItemViewModel>();

            foreach (var feedback in feedbacks)
            {
                model.Add(new ReviewItemViewModel()
                {
                    CommentDate = feedback.CreateDate,
                    UserName = feedback.UserId.HasValue ? GetUsernameById(feedback.UserId.Value) : null,
                    FullName = feedback.FullName,
                    CommentText = feedback.Comment,
                    DriverRate = new TaxiRating() { Rating = feedback.DriverRating },
                    PriceRate = new TaxiRating() { Rating = feedback.PriceRating },
                    ServiceRate = new TaxiRating() { Rating = feedback.ServiceRating },
                    CarRate = new TaxiRating() { Rating = feedback.CarRating },
                    AvgRate = new TaxiRating() { Rating = (feedback.CarRating + feedback.ServiceRating + feedback.DriverRating + feedback.PriceRating) / 4 }

                });
            }
            return PartialView(model);
        }

        [HttpPost]
        public ActionResult AddReview(int id, AddReviewViewModel model)
        {
            if (ModelState.IsValid)
            {

                HttpContext.Profile.SetPropertyValue("FullName", model.CommenterName);
                HttpContext.Profile.Save();
                

                var feedbackDo = new CustomerFeedback()
                {
                    UserId = CurrentUserId,
                    CarRating = Convert.ToInt16(model.CarRate.Rating),
                    Comment = model.Comment,
                    CreateDate = DateTime.Now,
                    DriverRating = Convert.ToInt16(model.DriverRate.Rating),
                    IsApproved = false,
                    PriceRating = Convert.ToInt16(model.PriceRate.Rating),
                    ServiceRating = Convert.ToInt16(model.ServiceRate.Rating),
                };
                
                _feedbackManager.AddNewReview(feedbackDo, id);
                
            }
            return new EmptyResult();
        }


        private string GetUsernameById(Guid userId)
        {
            return _membershipManager.GetUserNameById(userId);
            
        }

        private List<TaxiItemViewModel> ConvertToViewModel(List<TaxiService> services)
        {
            var res = new List<TaxiItemViewModel>();
            foreach (var taxi in services)
            {
                res.Add(new TaxiItemViewModel() { 
                   
                    Id = taxi.Id,
                    Conditioning = taxi.Conditioning,
                    CreateDate = taxi.CreateDate,
                    HasMeter = taxi.HasMeter,
                    LogoPath = FileStoreHelper.GetTaxiSmallLogo(taxi.Id, Server),
                    MinPrice = taxi.PricePolicy.MinPrice,
                    Name = GetLocalizedName(taxi),
                    NoSmoking = taxi.NoSmoking,
                    PhoneNumber = taxi.Contacts.PhoneNumber,
                    PricePerKM = taxi.PricePolicy.PricePerKM,
                    Rating = new TaxiRating(){ Rating = taxi.AvgRating},
                    Reviews = taxi.ReviewsCount,
                    MinPriceKM = taxi.PricePolicy.MinPriceKM,
                    UpTo6KMPrice = taxi.PricePolicy.UpTo6KMPrice
                });
            }
            return res;
        }

        private List<SelectListItem> GetAllDistricts()
        {
            var dists = _taxiManager.GetAllDistricts();

            var result = new List<SelectListItem>();
            result.Add(new SelectListItem()
            {
                Text = ViewResources.TaxiStrings.AllDistrictOption,
                Value = "",
                Selected = true
            });
            foreach (var distDo in dists)
            {
                result.Add(new SelectListItem()
                {
                    Text = GetLocalizedName(distDo),
                    Value = distDo.Id.ToString()
                });
            }
            return result;
        }

    }
}
